/**
 * vuex 核心概念Module部分的运用.
 */

/**
 * 在一个模块化的打包系统中，您必须显式地通过 Vue.use() 来安装 Vuex：
 */
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);

/**
 * 用于展示demo1中的模块部分状态
 */
const moduleDemo1 = {
  namespaced: true,
  state: () => ({
    count: 0,
  }),
  mutations: {
    increment(state) {
      state.count++;
    },
    decrement(state) {
      state.count--;
    },
  },
  actions: {
    increment({ commit }) {
      commit("increment");
    },
    decrement({ commit }) {
      commit("decrement");
    },
    incrementIfOdd({ commit, state }) {
      if (state.count % 2 === 1) {
        commit("increment");
      }
    },
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit("increment");
      }, 1000);
    },
    incrementIfOddOnRootSum({ state, commit, rootState }) {
      if ((state.count + rootState.count) % 2 === 1) {
        commit("increment");
      }
    },
  },
  getters: {
    oddOrEven(state) {
      return state.count % 2 === 0 ? "偶数" : "奇数";
    },
    sumWithRootCount(state, getters, rootState) {
      return state.count + rootState.count;
    },
  },
  modules: {
    // 继承父模块的命名空间
    page: {
      state: () => ({ title: "demo1的page" }),
      getters: {
        test(state) {
          return state.title; // -> getters['demo1/test']
        },
      },
    },
    // 进一步嵌套命名空间
    code: {
      namespaced: true,
      state: () => ({ number: 721 }),
      getters: {
        numberType(state) {
          return state.number % 2 === 0
            ? "偶数:" + state.number
            : "奇数:" + state.number; // -> getters['demo1/code/numberType']
        },
      },
    },
  },
};

/**
 * demo2中的模块部分状态
 */
const moduleDemo2 = {
  namespaced: true,
  state: () => ({ count: 0 }),
  mutations: {
    increment(state) {
      state.count++;
    },
  },
  getters: {
    // 在这个模块的 getter 中，`getters` 被局部化了
    // 你可以使用 getter 的第四个参数来调用 `rootGetters`
    someGetter(state, getters, rootState, rootGetters) {
      let a = getters.someOtherGetter; // -> 'demo2/someOtherGetter'
      let b = rootGetters.someOtherGetter; // -> 'someOtherGetter'
      return a + b;
    },
    someOtherGetter: (state) => {
      return state.count * 2;
    },
  },
  actions: {
    someAction: {
      root: true,
      handler(namespacedContext, payload) {
        //namespacedContext.commit("incrementByObj", payload);
        namespacedContext.commit("increment");
      }, // -> 'someAction'
    },
  },
};

/**
 * 导入常量
 */
import { DECREMENT_NUMBER, DECREMENT_BY_OBJ } from "./mutation-types";

/**
 * 创建一个 store
 */
const store = new Vuex.Store({
  modules: {
    demo1: moduleDemo1,
    demo2: moduleDemo2,
  },
  state: {
    count: 0,
    name: "zxn",
    todos: [
      { id: 1, text: "吃早饭", done: true },
      { id: 2, text: "学习vue", done: true },
      { id: 3, text: "吃午饭", done: false },
    ],
  },
  getters: {
    count: (state) => {
      return state.count;
    },
    doneTodos: (state) => {
      return state.todos.filter((todo) => todo.done);
    },
    doneTodosCount: (state, getters) => {
      return getters.doneTodos.length;
    },
    getTodoById: (state) => (id) => {
      return state.todos.find((todo) => todo.id === id);
    },
    name: (state) => {
      return state.name;
    },
    someOtherGetter: (state) => {
      return state.count * 2;
    },
  },

  mutations: {
    increment(state) {
      state.count++;
    },
    incrementNumber(state, n) {
      state.count += n;
    },
    incrementByObj(state, payload) {
      state.count += payload.amount;
    },
    decrement(state) {
      state.count--;
    },
    [DECREMENT_NUMBER](state, n) {
      state.count -= n;
    },
    [DECREMENT_BY_OBJ](state, payload) {
      state.count -= payload.amount;
    },
    increment2(state) {
      state.count += 2;
    },
  },
  actions: {
    add5({ dispatch, commit }) {
      return dispatch("add6").then(() => {
        commit("decrement");
      });
    },
    add6({ commit }) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          commit("incrementNumber", 6);
          resolve();
        }, 1000);
      });
    },
    incrementNumber({ commit }, n) {
      setTimeout(() => {
        commit("incrementNumber", n);
      }, 1000);
    },
    incrementAsync2({ commit }, payload) {
      setTimeout(() => {
        commit("incrementByObj", payload);
      }, 1000);
    },
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit("increment");
      }, 1000);
    },
    decrement({ commit }) {
      commit("decrement");
    },
    increment(context) {
      context.commit("increment");
    },
  },
});

// 注册模块 `myModule`
store.registerModule("moduleDemo1", {});

/**
 * 向外暴露store实例对象
 * 将该实例导出，以便在其他组件中使用该数据仓库
 */
export default store;
